package com.hqs.listener.service;

import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Binder;
import android.os.IBinder;
import android.os.PowerManager;
import android.support.annotation.Nullable;

import com.hqs.common.utils.SharedPreferenceUtil;
import com.hqs.listener.app.Constant;
import com.hqs.listener.helper.Helper;
import com.hqs.listener.helper.HttpHelper;
import com.hqs.listener.model.FileModel;
import com.hqs.listener.utils.FileUtil;
import com.lzy.okgo.model.Progress;
import com.lzy.okserver.download.DownloadListener;

import java.io.File;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

import io.realm.Realm;
import io.realm.RealmResults;

/**
 * Created by super on 2017/11/14.
 */

public class MusicService extends Service {

    private MediaPlayer mp;
    private int sec;
    private boolean isDownloading = false;
    private TimeChangedListener timeChangedListener;
    private int currentDownload = 0;
    private HttpHelper.DownloadFileListener listener;
    private File currentFile;
    private int chapterIndex = 0;
    private int currentPlayIndex = 0;
    private String[] chapters;
    private TimerThread timerThread;
    private PowerManager.WakeLock wakeLock;
    private int currentPosition = 0;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    private final IBinder mBinder = new LocalBinder();


    @Override
    public void onCreate() {
        super.onCreate();
        chapterIndex = SharedPreferenceUtil.get("chapterIndex", 0);
        currentPlayIndex = SharedPreferenceUtil.get("currentPlayIndex", 0);
        String curFile = SharedPreferenceUtil.get("currentFile", "");
        if (curFile.length() > 0) {
            File file = new File(curFile);
            if (file.exists()){
                setCurrentFile(file);
            }
        }
        getAllChapter();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, flags, startId);
    }

    public void play(File file){
        try {
            if(currentFile != null && currentFile.getName().equals(file.getName()) && mp != null){
                start();
                return;
            }
            this.currentFile = file;
            if (mp != null){
                mp.stop();
                mp.release();
                mp = null;
            }
            mp = MediaPlayer.create(this, Uri.fromFile(file));
            currentPosition = 0;
            sendMsg("file: " + getCurrentFileName());
            start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public void start(){
        try {
            mp.seekTo(currentPosition);
            mp.start();
            SharedPreferenceUtil.set("isPlaying", true);
            SharedPreferenceUtil.set("currentFile", currentFile.getAbsolutePath());
            SharedPreferenceUtil.set("currentPlayIndex", currentPlayIndex);
            SharedPreferenceUtil.set("chapterIndex", chapterIndex);
            sendMsg("start");
            sendMsg("currentPlayingChanged");

            mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mediaPlayer) {
                    playNextMusic();
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void pause(){
        try {
            SharedPreferenceUtil.set("currentFile", currentFile.getAbsolutePath());
            currentPosition = mp.getCurrentPosition() - 1000;
            if (currentPosition < 0){
                currentPosition = 0;
            }
            SharedPreferenceUtil.set("currentPosition", currentPosition);
            SharedPreferenceUtil.set("currentDuration", mp.getDuration());
            SharedPreferenceUtil.set("isPlaying", false);
            mp.pause();
            sendMsg("pause");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void playPreMusic(){
        try {
            if (currentPlayIndex == 0 && chapterIndex == 0){
                chapterIndex = chapters.length - 1;
                RealmResults<FileModel> models = models();
                currentPlayIndex = models.size() - 1;

                File file = new File(FileUtil.dataDir() + models.get(currentPlayIndex).fullPath);
                play(file);
                return;
            }

            if(currentPlayIndex == 0){
                chapterIndex -= 1;
            }
            RealmResults<FileModel> models = models();
            currentPlayIndex -= 1;
            if (currentPlayIndex == -1){
                currentPlayIndex = models.size() - 1;
            }

            File file = new File(FileUtil.dataDir() + models.get(currentPlayIndex).fullPath);
            play(file);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void playNextMusic(){
        try {
            RealmResults<FileModel> models = models();

            if (currentPlayIndex == models.size() - 1 && chapterIndex == chapters.length - 1){
                currentPlayIndex = 0;
                chapterIndex = 0;
                models = models();
                File file = new File(FileUtil.dataDir() + models.get(currentPlayIndex).fullPath);
                play(file);
                return;
            }

            currentPlayIndex += 1;
            if(currentPlayIndex == models.size()){
                currentPlayIndex = 0;
                chapterIndex += 1;
            }
            models = models();

            File file = new File(FileUtil.dataDir() + models.get(currentPlayIndex).fullPath);
            play(file);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private RealmResults<FileModel> models(){
        Realm realm = Realm.getDefaultInstance();
        return realm.where(FileModel.class).equalTo("path2", chapters[chapterIndex]).findAll();
    }

    public void sendMsg(String msg){
        Intent intent = new Intent("music_action");
        intent.putExtra("msg", msg);
        sendBroadcast(intent);
    }

    public boolean isPlaying() {
        if (mp == null){
            return false;
        }
        return mp.isPlaying();
    }

    public MediaPlayer getMediaPlayer() {
        return mp;
    }

    public void setTime(final int total){

        if (wakeLock == null) {
            PowerManager pm = (PowerManager)getSystemService(POWER_SERVICE);
            wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, this.getClass().getCanonicalName());
            wakeLock.acquire(); //设置保持唤醒
        }

        this.sec = total;
        if (timerThread != null){
            timerThread.running = false;
            timerThread = null;
        }
        timerThread = new TimerThread(new Runnable() {
            @Override
            public void run() {
                sec -= 1;
                if (sec >= 0){
                    updateTime();
                }
                else {
                    stopTimer();
                }
            }
        });
        timerThread.start();
    }
    public void stopTimer(){
        sec = 0;
        if (timerThread != null){
            timerThread.running = false;
            timerThread = null;
        }
        if (wakeLock != null && wakeLock.isHeld()){
            wakeLock.release();
            wakeLock = null;
        }
        // 停止播放
        pause();
    }

    public void updateTime(){
        if (timeChangedListener != null) {
            timeChangedListener.timeChanged(this.sec);
        }
    }

    public void downloadAll(HttpHelper.DownloadFileListener listener){
        this.listener = listener;
        if (isDownloading) {
            return;
        }
        Helper.doInBackground(new Runnable() {
            @Override
            public void run() {
                isDownloading = true;
                Realm realm = Realm.getDefaultInstance();
                RealmResults<FileModel> models = realm.where(FileModel.class).findAll();
                if (models == null || models.size() == 0) {
                    return;
                }
                else {
                    int i;
                    currentDownload = 0;
                    while (isDownloading){
                        if (currentDownload == -1){
                            return;
                        }
                        i = currentDownload;
                        download(i);
                        while (currentDownload == i && isDownloading);
                    }
                }
            }
        });
    }

    private void download(final int current){
        Realm realm = Realm.getDefaultInstance();
        RealmResults<FileModel> models = realm.where(FileModel.class).findAll();

        String dir = FileUtil.dataDir();
        final FileModel model = models.get(current);
        dir += model.getPath1() + "/" + model.originPath2 + "/";
        File file = new File(dir);
        if (!file.exists()) {
            file.mkdirs();
        }
        file = new File(dir, model.fileName);
        if (model.exists && file.exists()) {
            if (current + 1 == models.size()){
                currentDownload = -1;
                if (listener != null){
                    listener.onProgress(null, "completed");
                }
            }
            else {
                currentDownload = current + 1;
            }
            return;
        }

        final String fileName = model.fileName;
        HttpHelper.download(Constant.uServer + model.fullPath, dir, fileName, new DownloadListener(model.fileName) {
            @Override
            public void onStart(Progress progress) {
                if (listener != null){
                    listener.onProgress(progress, fileName);
                }
            }

            @Override
            public void onProgress(Progress progress) {
                if (listener != null){
                    listener.onProgress(progress, fileName);
                }
            }

            @Override
            public void onError(Progress progress) {
                onFinish(null, progress);
            }

            @Override
            public void onFinish(File file, Progress progress) {
                Realm realm = Realm.getDefaultInstance();
                RealmResults<FileModel> models = realm.where(FileModel.class).findAll();

                realm.beginTransaction();
                FileModel fileModel = models.get(current);
                fileModel.exists = true;
                realm.commitTransaction();
                realm.close();

                if (current + 1 == models.size()) {
                    if (listener != null){
                        listener.onProgress(progress, "completed");
                    }
                }
                else {
                    currentDownload = current + 1;
                }
            }

            @Override
            public void onRemove(Progress progress) {
                onFinish(null, progress);
            }
        });
    }

    public boolean isDownloading(){
        return isDownloading;
    }

    public void setCurrentFile(File file){
        if (this.currentFile == null || !this.currentFile.getName().equals(file.getName())){
            this.currentFile = file;
            if (mp != null){
                mp.stop();
                mp.release();
            }
            mp = MediaPlayer.create(this, Uri.fromFile(file));
        }
    }

    public void setChapterIndex(int chapterIndex) {
        this.chapterIndex = chapterIndex;
    }

    public String getCurrentFileName(){
        if(currentFile == null){
            return "";
        }
        return currentFile.getName().substring(0, currentFile.getName().length() - 4);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        try {
            SharedPreferenceUtil.set("currentFile", currentFile.getAbsolutePath());
            currentPosition = mp.getCurrentPosition() - 1000;
            if (currentPosition < 0){
                currentPosition = 0;
            }
            SharedPreferenceUtil.set("currentPosition", currentPosition);
            SharedPreferenceUtil.set("currentDuration", mp.getDuration());

            if (mp != null){
                mp.stop();
                mp.release();
                mp = null;
            }
            stopTimer();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public String[] getChapters() {
        return chapters;
    }

    private void getAllChapter(){
        Helper.doInBackground(new Runnable() {
            @Override
            public void run() {
                Realm realm = Realm.getDefaultInstance();
                RealmResults<FileModel> models = realm.where(FileModel.class).findAll();
                Set<String> hashSet = new HashSet<>();
                for (FileModel model : models){
                    hashSet.add(model.originPath2);
                }
                String[] sortedArray = new String[hashSet.size()];
                int i = 0;
                for (String s : hashSet){
                    sortedArray[i] = s;
                    i += 1;
                }
                Arrays.sort(sortedArray);

                i = 0;
                for(String s: sortedArray){
                    sortedArray[i] = s.substring(3);
                    i += 1;
                }
                chapters = sortedArray;
            }
        });
    }

    @Override
    public boolean onUnbind(Intent intent) {
        return super.onUnbind(intent);
    }

    @Override
    public void onRebind(Intent intent) {
        super.onRebind(intent);
    }

    public class LocalBinder extends Binder {

        public MusicService getService() {
            return MusicService.this;
        }
    }

    public void setTimeChangedListener(TimeChangedListener timeChangedListener) {
        this.timeChangedListener = timeChangedListener;
    }

    public interface TimeChangedListener {
        void timeChanged(int sec);
    }

    public void setCurrentPlayIndex(int currentPlayIndex) {
        this.currentPlayIndex = currentPlayIndex;
    }

    public String getChapter() {
        return chapters[chapterIndex];
    }

    public int getCurrentPlayIndex() {
        return currentPlayIndex;
    }

    public TimerThread getTimerThread() {
        return timerThread;
    }

    public class TimerThread extends Thread{
        public boolean running = true;
        public Runnable task;

        public TimerThread(Runnable task){
            this.task = task;
        }

        @Override
        public void run() {

            while (running){
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if(task != null && running){
                    task.run();
                }
            }
        }
    }

}
